<template>
  <div class="lc-cesium">
    <div class="lc-cesium_map" id="cesium-3d-viewer"></div>
    <div v-if="loading" class="loading-indicator">地图加载中...</div>
    <div v-if="error" class="error-message">地图加载失败: {{ error }}</div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import { createInfoCanvas } from "../../tools/canvas";
import {
  Viewer,
  Cartesian3,
  Color,
  WebMapTileServiceImageryProvider,
  NearFarScalar,
} from "cesium";
import * as Cesium from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
import { pointInfo, type pointProps } from "./type.ts";
import {cesiumProps} from "./props.ts";

const loading = ref(true);
const error = ref<string | null>(null);

let viewer: Viewer | null = null;
const pointEntities: Cesium.Entity[] = [];

const {
  centerPosition = Cartesian3.fromDegrees(114.155799, 22.617691, 90000),
  controlStatus
} = defineProps(cesiumProps)

// 初始化3D视图
function initViewer(): void {
  try {
    viewer = new Viewer("cesium-3d-viewer", controlStatus);

    // 移除默认底图
    viewer.imageryLayers.remove(viewer.imageryLayers.get(0));

    // 优化性能设置
    viewer.scene.debugShowFramesPerSecond = false;
    // viewer.scene.screenSpaceCameraController.inertia = 0.9;
    viewer.scene.screenSpaceCameraController.enableTranslate = true;
    viewer.scene.screenSpaceCameraController.minimumZoomDistance = 1000;
    viewer.scene.screenSpaceCameraController.maximumZoomDistance = 90000;
    viewer.scene.globe.baseColor = Color.TRANSPARENT;

    //poiont双击事件取消
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    );

    setupClickHandler(viewer);

    // 设置初始视角
    viewer.camera.setView({ destination: centerPosition });
  } catch (err) {
    error.value = `初始化Viewer失败: ${
      err instanceof Error ? err.message : String(err)
    }`;
    loading.value = false;
  }
}

// 加载瓦片地图服务
async function addTileLayer(): Promise<void> {
  if (!viewer) return;

  try {
    const tkUrl =
      "http://t3.tianditu.gov.cn/vec_w/wmts?tk=666e7c17a9350414b1e66d099d07e654";
    // 自定义瓦片服务

    const provider = new WebMapTileServiceImageryProvider({
      url: tkUrl,
      layer: "vec",
      style: "default",
      format: "image/png",
      tileMatrixSetID: "w",
      maximumLevel: 20, // 提高层级
      tilingScheme: new Cesium.WebMercatorTilingScheme(), // 强制 WebMercator
    });

    if (viewer) {
      // 添加图层
      viewer.imageryLayers.addImageryProvider(provider);
    }
  } catch (err) {
    error.value = `加载瓦片地图服务失败: ${
      err instanceof Error ? err.message : String(err)
    }`;
    loading.value = false;
  }
}

async function addMarker(point: pointProps, type?: string) {
  // if (!viewer) return;

  // viewer.entities.removeAll();

  const valueInfo = await createInfoCanvas(point, type);
  const entity = viewer?.entities.add({
    position: Cartesian3.fromDegrees(point.lng, point.lat),
    name: type ? point.name : point.name + "Label",
    billboard: {
      image: valueInfo.canvas,
      disableDepthTestDistance: type ? 8000 : 8888,
      pixelOffset: type
        ? new Cesium.Cartesian2(0, 0)
        : new Cesium.Cartesian2(104, 18), // 右20px，下20px
      scale: type ? 1 : 0.9,
      // scaleByDistance: new NearFarScalar(1.0e3, 1.5, 2.0e3, 0.9), // 随距离缩放
      translucencyByDistance: new NearFarScalar(1.0e3, 1.0, 2.0e3, type ? 0.9 : 1), // 随距离淡出
    },
  });

  if (entity) pointEntities.push(entity);

  // setTimeout((valueInfo.cleanup), 1000)
}

// 初始化点击事件处理
function setupClickHandler(viewer: Cesium.Viewer) {
  const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

  handler.setInputAction((click: any) => {
    const pickedObject = viewer.scene.pick(click.position);
    if (Cesium.defined(pickedObject) && pickedObject.id) {
      const clickedEntity = pickedObject.id;
      const findValue = pointInfo.findIndex(
        (item) => item.name === clickedEntity.name
      );
      const findLabelValue = pointEntities.findIndex(
        (item) => item.name === clickedEntity.name + "Label"
      );
      if (findValue != -1 && findLabelValue == -1) {
        addMarker(pointInfo[findValue]);
      }

      pointEntities.forEach((item) => {
        const nameValue = item.name;
        if (nameValue?.slice(-5) === "Label") item.show = clickedEntity.name + 'Label' === nameValue && !item.show;
      });
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}

// 初始化地图
async function initMap(): Promise<void> {
  try {
    initViewer();
    await addTileLayer();
    pointInfo.forEach((item) => addMarker(item, "value"));
    loading.value = false;
  } catch (err) {
    error.value = `地图初始化失败: ${
      err instanceof Error ? err.message : String(err)
    }`;
    loading.value = false;
    console.error("Map initialization failed:", err);
  }
}

onMounted(() => {
  initMap();
});

onBeforeUnmount(() => {
  if (viewer && !viewer.isDestroyed()) {
    viewer.destroy();
    viewer = null;
  }
});
</script>

<style lang="scss" scoped>
.lc-cesium {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  padding: 20px;
  width: 100%;
  height: 100%;
  box-sizing: border-box;

  &_map {
    position: relative;
    width: 100%;
    height: 100%;
  }

  .loading-indicator,
  .error-message {
    position: absolute;
    top: 20px;
    left: 50%;
    transform: translateX(-50%);
    padding: 10px 20px;
    width: 50%;
    background: rgba(0, 0, 0, 0.7);
    color: white;
    border-radius: 4px;
    z-index: 999;
    text-align: center;
  }

  .error-message {
    background: rgba(255, 0, 0, 0.7);
  }
}
</style>
